/*
 * © 2024 huayunliufeng保留所有权利, 依据MIT许可证发布。
 * 请勿更改或删除版权声明或此文件头。
 * 此代码是免费软件, 您可以重新分发和/或修改它。
 * 开源是希望它有用, 但不对代码做任何保证。
 * 如有疑问请联系: huayunliufeng@163.com
 */

package io.github.huayunliufeng.common.utils;

import lombok.extern.slf4j.Slf4j;

import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.Base64;

/**
 * 和字节操作相关的工具类
 *
 * @author huayu 2024/5/10 15:29
 * @version 0.0.4
 * @since 0.0.7-2
 */
@Slf4j
public class HylfByteUtil {
    public static final Base64.Encoder base64Encoder = Base64.getEncoder();
    public static final Base64.Decoder base64decoder = Base64.getDecoder();

    /**
     * 将图像转换为base64编码
     *
     * @param is 数据流
     * @return base64编码的字符串
     */
    public static String imageToBase64(InputStream is) {
        byte[] imageBytes = readAllBytes(is);
        // 使用Base64进行编码
        return base64Encoder.encodeToString(imageBytes);
    }

    /**
     * 将图像转换为base64编码
     *
     * @param imagePath 图片路径
     * @return base64编码的字符串
     */
    public static String imageToBase64(String imagePath) {
        byte[] imageBytes = readAllBytes(imagePath);
        // 使用Base64进行编码
        return base64Encoder.encodeToString(imageBytes);
    }

    /**
     * 读取文件的所有字节。
     *
     * @param filename 指定文件路径
     * @return byte[]
     */
    public static byte[] readAllBytes(String filename) {
        ClassLoader classLoader = HylfByteUtil.class.getClassLoader();
        InputStream is = classLoader.getResourceAsStream(filename);
        return readAllBytes(is);
    }

    /**
     * 读取文件的所有字节。
     *
     * @param is 文件流
     * @return byte[]
     */
    public static byte[] readAllBytes(InputStream is) {
        try {
            if (is != null) {
                // 将输入流转换为通道，以便更高效地读取字节
                ReadableByteChannel channel = Channels.newChannel(is);
                // 创建缓冲区以容纳文件的所有字节
                ByteBuffer buffer = ByteBuffer.allocate(is.available());
                // 读取通道中的所有字节到缓冲区
                channel.read(buffer);
                // 将缓冲区.flip()以准备读取数据
                buffer.flip();
                return buffer.array();
            }
        } catch (Exception e) {
            log.error("读取文件的byte数组失败。[InputStream = {}]", is);
            throw new RuntimeException(e);
        } finally {
            HylfFunUtil.autoClose(is);
        }
        return new byte[0];
    }

}
